/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.ceair.flight.refund.service.cronjob.autocheck.impl;

import com.ceair.flight.refund.service.cronjob.autocheck.IRescheduleChcker;
//import com.ceair.muss.inside.webservice.flightdata.outer.*;
import com.ceair.fois.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import javax.annotation.PostConstruct;
import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;

/**
 *
 * @author youguilin
 */
@Service
public class RescheduleChckerImpl implements IRescheduleChcker {

    private static final Logger LOG = LoggerFactory.getLogger(RescheduleChckerImpl.class);

    private static final String CANCEL_FLAG = "取消";
    private static final String DELAY_FLAG = "延误";

    @Value("${flight.realstatus.service.host}")
    private String serviceHost;//="http://ws-outer-fois.ceair.com:8100/FlightDataService.asmx";
    @Value("${flight.realstatus.service.loginId}")
    private String loginServiceId;// = "muovc";
    @Autowired
    private FlightDataServiceSoap realFlightService;

    @PostConstruct
    void inital() {
        Assert.notNull(serviceHost, "Reschedule checker service host is not set");
        Assert.notNull(loginServiceId, "Reschedule checker service id is not set");
    }

    @Override
    public boolean isReschedule(String flightNo, Date depDate, String depAirport, String arrAirport) {
        LOG.info("Checking flight:{} if it is rescheduled with param depDate:{}, depAirport:{}, arrAirport:{}", flightNo, depDate, depAirport, arrAirport);
        String carrir = getCarrir(flightNo);
        String flightNumber = getFlightNumber(flightNo);
        QueryResult result = getFlightDetail(carrir, flightNumber, depDate, depAirport, arrAirport);
        return isReschedule(result);
    }

    /**
     * 获取航班航空公司
     *
     * @param flightNo
     * @return
     */
    private String getCarrir(String flightNo) {
        String carrir = flightNo.substring(0, 2);
        LOG.debug("Flight No {}'s carrir is {}", flightNo, carrir);
        return carrir;
    }

    /**
     * 获取航班号
     *
     * @param flightNo
     * @return
     */
    private String getFlightNumber(String flightNo) {
        String number = flightNo.substring(2);
        LOG.debug("Flight No {}'s number is {}", flightNo, number);
        return number;
    }

    private QueryResult getFlightDetail(String carrir, String flightNumber, Date depDate, String depAirport, String arrAirport) {
        try {
            GregorianCalendar c = new GregorianCalendar();
            c.setTime(depDate);
            XMLGregorianCalendar flightDate = DatatypeFactory.newInstance().newXMLGregorianCalendar(c);
            QueryResult queryResult = realFlightService.getFlightFSInfoService(loginServiceId, flightDate, carrir, flightNumber, depAirport, arrAirport);
            return queryResult;
        } catch (DatatypeConfigurationException ex) {
            LOG.error("Date format error", ex);
        }
        LOG.error("Query real flight information failed");
        return null;
    }

    private boolean isReschedule(QueryResult result) {
        if (result == null || !result.isIsSuccess()) {
            LOG.warn("Got response from real flight service error:{}", result != null ? result.getErrorMessage() : "Unknow cause");
            return false;
        }
        LOG.info("Got response from real flight service success");
        ArrayOfAnyType flightData = result.getData();
        if (flightData == null) {
            LOG.warn("No flight data in real flight service response");
            return false;
        }
        List<Object> flightList = flightData.getItem();
        if (flightList == null || flightList.isEmpty()) {
            LOG.warn("Flight list is empty in real flight service response");
            return false;
        }

        for (Object flightO : flightList) {
            FLIGHTFS flight = (FLIGHTFS) flightO;
            ArrayOfFLIGHTLEGSALE saleFlight = flight.getActualFlights();
            if (saleFlight == null) {
                LOG.info("Actual flight list object is null");
                continue;
            }
            List<FLIGHTLEGSALE> flights = saleFlight.getActualFlight();
            if (flights == null || flights.isEmpty()) {
                LOG.info("Actual flight list is null or empty");
                continue;
            }
            for (FLIGHTLEGSALE reFlight : flights) {
                String delayStr = reFlight.getDELAYREMARK();
                String statusStr = reFlight.getSTATUS();
                if (delayStr != null && delayStr.contains(DELAY_FLAG)) {
                    LOG.info("Flight is delayed");
                    return true;
                }
                if (statusStr != null && statusStr.contains(CANCEL_FLAG)) {
                    LOG.info("Flight is canceled");
                    return true;
                }
                LOG.info("Flight status value:{}, delay remark value:{}", statusStr, delayStr);
            }
        }
        LOG.warn("Could not determine the flight is rescheduled");
        return false;
    }

}
